Czy powinienem używać' has key () ' lub 'in' w pythonowych dictach?

Zastanawiam się, co jest lepsze do zrobienia:

d = {'a': 1, 'b': 2}
'a' in d
True

Lub:

d = {'a': 1, 'b': 2}
d.has_key('a')
True
Author: smci, 2009-08-24

9 answers

in jest zdecydowanie bardziej pythoniczny.

W rzeczywistości has_key() został usunięty w Pythonie 3.x .

 1402
Author: tonfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-30 15:56:24

in wygrywa z rąk, nie tylko w elegancji (i nie jest przestarzały; -), ale także w wykonaniu, np.: {]}

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop

Podczas gdy poniższe spostrzeżenie nie jest prawdą zawsze, zauważysz, że zazwyczaj, w Pythonie szybsze rozwiązanie jest bardziej eleganckie i Pythoniczne; dlatego {2]} jest tak pomocne-nie jest tylko o oszczędzaniu stu nanosekund tu i tam!-)

 258
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-24 18:12:28

Według Pythona docs :

has_key() jest przestarzały na rzecz key in d.

 100
Author: Nadia Alramli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 06:27:21

Użyj dict.has_key() jeśli (i tylko jeśli) twój kod musi być uruchamiany przez Pythona w wersjach wcześniejszych niż 2.3 (kiedy key in dict został wprowadzony).

 44
Author: John Machin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-18 16:52:17

Jest jeden przykład, w którym in faktycznie zabija twój występ.

Jeśli użyjesz in na kontenerze O (1), który implementuje tylko __getitem__ i has_key(), ale nie __contains__, zamienisz Wyszukiwanie O(1) w wyszukiwanie O(N) (ponieważ in wraca do wyszukiwania liniowego przez __getitem__).

Poprawka jest oczywiście trywialna:

def __contains__(self, x):
    return self.has_key(x)
 23
Author: schlenk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-18 16:45:39

Rozwiązanie do dict.has_key() jest przestarzałe, użyj 'in' -- Sublime text editor 3

Tutaj wziąłem przykład słownika nazwanego 'wiek' -

ages = {}

# Add a couple of names to the dictionary
ages['Sue'] = 23

ages['Peter'] = 19

ages['Andrew'] = 78

ages['Karren'] = 45

# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:

    print "Sue is in the dictionary. She is", ages['Sue'], "years old"

else:

    print "Sue is not in the dictionary"
 17
Author: Greena modi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-11 19:46:11

Rozszerzenie testów wydajności Alexa Martelli z komentarzami Adama Parkina...

$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
    x = t.timeit(number)
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
    d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(  99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop
 17
Author: Bruno Bronosky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 16:11:04

has_key jest metodą słownikową, ale in będzie działać na dowolnej kolekcji, a nawet jeśli __contains__ nie ma, in użyje dowolnej innej metody do iteracji kolekcji, aby się dowiedzieć.

 15
Author: u0b34a0f6ae,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-24 18:35:22

Jeśli masz coś takiego:

t.has_key(ew)

Zmień to na poniżej, aby uruchomić w Pythonie 3.X i wyżej:

key = ew
if key not in t
 -3
Author: Harshita Jhavar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-19 17:13:55